package com.vip8.recorder.service.service.impl;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.vip8.recorder.api.model.dto.DeviceLogDTO;
import com.vip8.recorder.api.model.dto.OssToken;
import com.vip8.recorder.api.model.params.ApkParam;
import com.vip8.recorder.service.constant.ValidEnum;
import com.vip8.recorder.service.db.mapper.AppVersionDao;
import com.vip8.recorder.service.db.mapper.DeviceLogDao;
import com.vip8.recorder.service.db.model.AppVersion;
import com.vip8.recorder.service.db.model.AppVersionExample;
import com.vip8.recorder.service.db.model.DeviceLog;
import com.vip8.recorder.service.db.model.DeviceLogExample;
import com.vip8.recorder.service.service.DeviceManageService;
import com.vip8.recorder.service.service.OssManageService;
import com.vip8.recorder.service.utils.BeanCopyUtil;
import com.vip8.recorder.service.utils.CollectionUtil;
import com.vip8.recorder.service.utils.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DeviceManageServiceImpl implements DeviceManageService {
    @Resource
    private AppVersionDao versionDao;
    @Resource
    private OssManageService ossManageService;
    @Value("${oss.apkDir}")
    private String apkDir;

    @Value("${oss.logFileDir}")
    private String logFileDir;
    @Value("${oss.endPoint}")
    private String endPoint;

    @Value("${oss.bucketName}")
    private String bucketName;

    @Resource
    private DeviceLogDao deviceLogDao;


    @Override
    public boolean updateApkPatch(ApkParam appInfo, MultipartFile apk) {
        String fileKey = null;
        if (apk != null && apk.getSize() > 0) {
            fileKey = String.format("%s%s", apkDir, apk.getOriginalFilename());
            try {
                OssToken ossToken = ossManageService.getOssToken();
                ClientConfiguration cfg = new ClientConfiguration();
                cfg.setMaxConnections(200);
                cfg.setConnectionTimeout(5000);
                cfg.setSocketTimeout(5000);
                cfg.setMaxErrorRetry(3);

                OSSClient ossClient2 = new OSSClient(endPoint, ossToken.getAccessKeyId(), ossToken.getAccessKeySecret(), ossToken.getSecurityToken(), cfg);
                InputStream inputStream = apk.getInputStream();
                ossClient2.putObject(bucketName, fileKey, inputStream);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        AppVersion appVersion = new AppVersion();
        BeanCopyUtil.copyBean(appInfo, appVersion);
        appVersion.setDownloadUrl(fileKey);
        if (appInfo.getValid() != null) {
            appVersion.setValid(appInfo.getValid().byteValue());
        }
        AppVersionExample example = new AppVersionExample();
        AppVersionExample.Criteria criteria = example.createCriteria();
        criteria.andVersionEqualTo(appInfo.getVersion());
        criteria.andValidEqualTo(ValidEnum.VALID.getFlag());
        List<AppVersion> versions = versionDao.selectByExample(example);
        if (CollectionUtil.isEmpty(versions)) {
            versionDao.insertSelective(appVersion);
        } else {
            versionDao.updateByExampleSelective(appVersion, example);
        }
        return true;
    }

    @Override
    public boolean updateAppLogFile(ApkParam appInfo, MultipartFile file) {
        String fileKey = null;
        if (file != null && file.getSize() > 0) {
            fileKey = String.format("%s%s/%s-%s", logFileDir, appInfo.getDeviceId(),file.getOriginalFilename(), "" + System.currentTimeMillis());
            try {
                OssToken ossToken = ossManageService.getOssToken();
                ClientConfiguration cfg = new ClientConfiguration();
                cfg.setMaxConnections(200);
                cfg.setConnectionTimeout(5000);
                cfg.setSocketTimeout(5000);
                cfg.setMaxErrorRetry(3);

                OSSClient ossClient2 = new OSSClient(endPoint, ossToken.getAccessKeyId(), ossToken.getAccessKeySecret(), ossToken.getSecurityToken(), cfg);
                InputStream inputStream = file.getInputStream();
                ossClient2.putObject(bucketName, fileKey, inputStream);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setDeviceId(appInfo.getDeviceId());
        deviceLog.setPhone(appInfo.getPhone());
        deviceLog.setVersion(appInfo.getVersion());
        deviceLog.setLogUrl(fileKey);

        deviceLogDao.insertSelective(deviceLog);
        return true;
    }

    @Override
    public List<DeviceLogDTO> queryAppLogFile(ApkParam appInfo) {
        DeviceLogExample example = new DeviceLogExample();
        DeviceLogExample.Criteria criteria = example.createCriteria();

        if (StringUtil.isNotEmpty(appInfo.getDeviceId())) {
            criteria.andDeviceIdEqualTo(appInfo.getDeviceId());
        }
        if (appInfo.getVersion() != null) {
            criteria.andVersionEqualTo(appInfo.getVersion());
        }
        if(StringUtil.isNotEmpty(appInfo.getPhone())){
            criteria.andPhoneEqualTo(appInfo.getPhone());
        }
        if (appInfo.getStartTime() != null && appInfo.getEndTime() != null) {
            criteria.andGmtCreateBetween(appInfo.getStartTime(), appInfo.getEndTime());
        }
        List<DeviceLog> deviceLogs = deviceLogDao.selectByExample(example);
        if (CollectionUtil.isNotEmpty(deviceLogs)) {
            return deviceLogs.stream().map(item -> {
                DeviceLogDTO deviceLogDTO = new DeviceLogDTO();
                BeanCopyUtil.copyBean(item, deviceLogDTO);
                if(StringUtil.isNotEmpty(item.getLogUrl())){
                    String url = ossManageService.getUrlByFileKey(item.getLogUrl());
                    deviceLogDTO.setLogUrl(url);
                }
                return deviceLogDTO;
            }).collect(Collectors.toList());
        }
        return null;
    }

    private Map<String, String> extractMetadata(MultipartFile file) {
        Map<String, String> metadata = new HashMap<>();
        metadata.put("Content-Type", file.getContentType());
        metadata.put("Content-Length", String.valueOf(file.getSize()));
        return metadata;
    }
}
